﻿#include <tcp_socket.h>

tcp_socket::tcp_socket(qintptr socketDescriptor)
{
    this->socketDescriptor=socketDescriptor;
    connect(this,SIGNAL(readyRead()),this,SLOT(receive()));
    LastConnectTime=QDateTime::currentDateTime();
}

tcp_socket::~tcp_socket()
{
    disconnect(this,SIGNAL(readyRead()),this,SLOT(receive()));
    disconnectFromHost();
    close();
    qDebug()<<this->name<<"销毁";
}

bool tcp_socket::tcpSocket_init()
{
    if(!this->setSocketDescriptor(socketDescriptor))
    {
        qDebug()<<"tcp_socket设置setSocketDescriptor失败！";
        return false;
    }
    return true;
}


void tcp_socket::receive()
{
    receive_data+=read(bytesAvailable());
    if(receive_datasize!=0||receive_data.size()>=receive_datasize)
    {
        analyse_data();
    }
}

void tcp_socket::analyse_data()
{
    while(receive_data.size()>(sizeof(qint32)+sizeof(qint64)))
    {
        bool isCompress;
        qint64 data_size;
        qint32 feature;
        QByteArray data;
        QDataStream dts(&receive_data,QIODevice::ReadWrite);
        dts>>feature>>data_size;
        if(feature==this->feature)
        {
            if(data_size<=receive_data.size())
            {
                dts.device()->seek(sizeof(qint32)+sizeof(qint64));
                dts>>isCompress;
                dts>>data;
                receive_data.remove(0,data_size);

                if (!isCompress)
                {
                    process_data(data);
                }
                else
                {
                    process_data(qUncompress(data));
                }
            }
            else
            {
                break;
            }
        }
        else
        {
            qDebug()<<"特征值错误，断开socket";
            disconnectFromHost();
            break;
        }
    }
}


void tcp_socket::process_data(QByteArray data)
{
    this->LastConnectTime=QDateTime::currentDateTime();
    QString id,type,information;
    QStringList result=json_analyse(data);
    //qDebug()<<result;
    if(result.size()>=3)
    {
        id=result[0];
        type=result[1];
        information=result[2];
        if (type=="程序类型")
        {
            this->name=id;
            this->type=information;
        }
        emit this->send_ReplyData(id,type,information);
    }


}


QByteArray tcp_socket::json_pack(QString id, QString type, QString data)
{
    QJsonObject json;
    json.insert("id", id);
    json.insert("type", type);
    json.insert("data", data);
    QJsonDocument document;
    document.setObject(json);
    QByteArray byte_array = document.toJson(QJsonDocument::Compact);
    return byte_array;
}


QStringList tcp_socket::json_analyse(QByteArray data)
{
    QString id,type,message;
    QStringList result;
    QJsonParseError json_error;
    QJsonDocument parse_doucment = QJsonDocument::fromJson(data, &json_error);
    if(json_error.error == QJsonParseError::NoError)
    {
        if(parse_doucment.isObject())
        {
            QJsonObject obj = parse_doucment.object();
            if(obj.contains("id"))
            {
                QJsonValue id_value = obj.take("id");
                if(id_value.isString())
                {
                    id = id_value.toString();
                }
            }
            if(obj.contains("type"))
            {
                QJsonValue type_value = obj.take("type");
                if(type_value.isString())
                {
                    type = type_value.toString();
                }
            }
            if(obj.contains("data"))
            {
                QJsonValue data_value = obj.take("data");
                if(data_value.isString())
                {
                    message = data_value.toString();
                }
            }
            result<<id<<type<<message;
            // qDebug()<<"json解析结果为:"<<result;

        }
        else
        {
            qDebug()<<"json不是对象";
        }

    }
    else
    {
        qDebug()<<"json格式错误！";
    }
    return result;
}


void tcp_socket::send_data(QByteArray data)
{

    bool isCompress=false;
    if(data.size()>qCompress(data).size())
    {
        isCompress=true;
        data=qCompress(data);
    }
    QByteArray senddata;
    QDataStream dts(&senddata,QIODevice::WriteOnly);
    dts<<(qint32)0<<(qint64)0<<(bool)isCompress<<data;
    dts.device()->seek(0);
    dts<<feature;
    dts.device()->seek(sizeof(qint32));
    dts<<(qint64)senddata.size();
    //qDebug()<<senddata.size();
    write(senddata);
    flush();
    //  waitForBytesWritten();
}

void tcp_socket::send_message(QString id, QString type, QString data)
{
    send_data(json_pack(id,type,data));
}

void tcp_socket::send_messagefromslot(QString id, QString type, QString data, tcp_socket *t_socket, emit_type e_type, QString sockettype)
{
    if(t_socket==this||e_type==All)
    {
        if (sockettype.isEmpty()||sockettype==this->type)
        {

            send_data(json_pack(id,type,data));
        }
    }
}


void tcp_socket::disconnect_Allsocket()
{
    disconnectFromHost();
    deleteLater();
}

void tcp_socket::IsConnect()
{
    //如果上次通信时间大于300秒,判断Socket断开
    if(this->LastConnectTime.secsTo(QDateTime::currentDateTime())>300)
    {
        qDebug()<<"最后一次通信过长，断开连接!"<<this->name;
        this->disconnectFromHost();
    }
    else
    {
    //    qDebug()<<this->LastConnectTime.secsTo(QDateTime::currentDateTime())<<this->name;
    }
}

void tcp_socket::socket_delete(tcp_socket *socket)
{
    if(socket==this)
    {
        deleteLater();
    }
}
